package com.egaleye.core.exception;

import com.egaleye.core.response.CodeEnum;

import java.text.MessageFormat;
import java.util.Arrays;
import java.util.StringJoiner;

public class BaseException extends RuntimeException{

    /**
     * serialVersionUID
     */
    private static final long serialVersionUID = 1L;

    /**
     * 所属应用
     */
    private String app;

    /**
     * 错误码对应的参数
     */
    private Object[] args;

    /**
     * 错误码
     */
    private CodeEnum codeEnum;

    public BaseException(){

    }

    /**
     * 构造函数
     *
     * @param message 异常信息
     */
    public BaseException(String message) {
        this(message, null);
    }

    /**
     * 构造函数
     *
     * @param codeEnum 类型
     * @param message  异常信息
     */
    public BaseException(CodeEnum codeEnum, String message) {
        this(message, null, codeEnum);
    }

    /**
     * 构造函数
     *
     * @param throwable 异常
     */
    public BaseException(Throwable throwable) {
        this(null, throwable);
    }

    /**
     * 构造函数
     *
     * @param message   异常信息
     * @param throwable 异常
     */
    public BaseException(String message, Throwable throwable) {
        this("topcloud", CodeEnum.UNKNOWN_ERROR, new String[]{message}, throwable);
    }

    /**
     * 构造函数
     *
     * @param message   异常信息
     * @param throwable 异常
     * @param codeEnum  类型
     */
    public BaseException(String message, Throwable throwable, CodeEnum codeEnum) {
        this("topcloud", codeEnum, new String[]{message}, throwable);
    }

    /**
     * 构造函数
     *
     * @param app      应用名称
     * @param codeEnum 错误码
     */
    public BaseException(String app, CodeEnum codeEnum, Throwable throwable) {
        this(app, codeEnum, null, throwable);
    }

    /**
     * 构造函数
     *
     * @param app      应用名称
     * @param codeEnum 错误码
     * @param args     参数
     */
    public BaseException(String app, CodeEnum codeEnum, Object[] args) {
        this(app, codeEnum, args, null);
    }

    /**
     * 构造函数
     *
     * @param app       应用名称
     * @param codeEnum  错误码
     * @param args      参数
     * @param throwable 异常
     */
    public BaseException(String app, CodeEnum codeEnum, Object[] args, Throwable throwable) {
        super(throwable);
        this.app = app;
        this.args = args;
        this.codeEnum = codeEnum;
    }

    /**
     * 获取应用名称
     *
     * @return app 应用名称
     */
    public String getApp() {
        return app;
    }

    /**
     * 获取参数
     *
     * @return args 参数
     */
    public Object[] getArgs() {
        return args != null ? args : new String[]{""};
    }

    /**
     * 获取错误码
     *
     * @return CodeEnum 业务错误码
     */
    public CodeEnum getCodeEnum() {
        return codeEnum != null ? codeEnum : CodeEnum.UNKNOWN_ERROR;
    }

    /**
     * 获取消息
     *
     * @return String 消息
     */
    @Override
    public String getMessage() {
        return MessageFormat.format(getCodeEnum().getMessage(), getArgs());
    }

    @Override
    public String toString() {
        return new StringJoiner(", ", BaseException.class.getSimpleName() + "[", "]")
                .add("app='" + app + "'")
                .add("args=" + Arrays.toString(args))
                .add("codeEnum=" + codeEnum)
                .toString();
    }

}
